Skip to content

Conversation

@ngholiza
Copy link
Collaborator

Why

Legacy MAX-phase XRD data from the Anasori lab (needed by Prof. Bilionis's group) must be modelled the way Prof. Strachan asked on 2026-10-08: each step is a unit process, linked through the sample. A furnace synthesis run produces a sample; an XRD run takes that sample and outputs its pattern.

What

  • Upload into an experiment. POST /api/data/uploads/{id}/process accepts experiment_type_id. Runs record the experiment (equipment_runs.experiment_type_id) and the template version they were captured under (experiment_type_version, kept on re-processing). GET /api/dataset/v2/runs?experiment_type_id= filters by it.
  • File outputs. POST /api/data/uploads/{id}/attachments stages files or a zip. At processing, outputs typed file/artifact are matched by the path in the CSV cell and stored per run (equipment_run_files, Postgres bytea, as the model registry does). Download via GET /api/dataset/v2/runs/{run_id}/files/{file_id}, scoped to the run's project.
  • Platform sample IDs (IGSN syntax). api/sample_ids.py. A sample_id output gets the ID derived from the run (equipment, project, lot, run instant, field); students can't invent IDs. A sample_id input must name a sample already registered in the same project. Runs link to samples (equipment_run_samples), and GET /api/dataset/v2/samples/{id}/lineage follows a sample across unit processes. Registering the namespace with DataCite/SESAR for global IGSN resolution is a follow-up.
  • Integrity and safety.
    • Runs, files and sample links are written in one transaction, and each touched run's replaced side is reconciled.
    • Processing requires project write access.
    • Attachments have limits (per-file, total, linked bytes), and the zip directory is validated before parsing.
    • The attachment/processing race is closed with a row lock.
    • Lineage has an explicit visibility check that holds even if RLS enforcement is off.
  • Web.
    • Upload page: experiment picker, "Attach files", and reprocess.
    • Equipment registration: sample_id type.
    • Run detail: stored files, samples, and experiment version.
  • scripts/legacy_xrd. The converter splits the lab's exports into synthesis.csv, xrd.csv and patterns.zip, using the platform's sample-ID function. Batch 1 (38 scans) validates end-to-end against the upload parser.

Migration

ensure_upload_experiment_and_run_files_pg() (in run_schema_migrations):

  • adds two columns to equipment_runs and one to data_uploads (metadata-only adds);
  • builds the experiment index with CREATE INDEX CONCURRENTLY and repairs an invalid one;
  • creates data_upload_files, equipment_run_files and equipment_run_samples with RLS policies.

Run the migration Job before rolling out the API, as usual.

Tests

  • 39 unit tests and 9 real-Postgres integration tests (migration run twice, RLS, atomic rollback, reconciliation, version preservation, sample chain and lineage).
  • Full API suite: 264 passed.
  • Converter tests pass.
  • next build passes.
  • Reviewed by Codex Astra over 4 rounds; approved.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ve21T1az57p9vrmYj8vdNe

Legacy MAX-phase XRD data (and future experiments) are modelled as unit
processes linked by samples, as agreed with Prof. Strachan: a furnace
synthesis run produces a sample; an XRD run takes that sample and outputs
its pattern file.

- Uploads can be processed into a chosen experiment template; runs record
  the experiment and the template version they were captured under (kept
  on re-processing).
- Outputs registered as "file"/"artifact" are matched to files attached to
  the upload (files or a zip) and stored per run in Postgres, with an
  RLS-scoped download endpoint.
- Platform-issued sample IDs in IGSN syntax (api/sample_ids.py): a
  sample_id output gets the ID derived from the run; a sample_id input must
  name a sample already registered in the same project. Runs link to the
  samples they produced or used, and a lineage endpoint follows a sample
  across unit processes.
- Runs, files and sample links are ingested in one transaction, and every
  touched run's replaced side is reconciled.
- Processing requires project write access; attachment uploads are bounded
  (per-file, total, linked bytes, zip directory checked before parsing).
- Web: experiment picker and "Attach files" on the upload page, sample_id
  type in equipment registration, stored files and samples on run detail.
- scripts/legacy_xrd: converter splits the lab's exports into synthesis.csv,
  xrd.csv and patterns.zip using the platform's sample-ID function.

Reviewed by Codex Astra (4 rounds, approved).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ve21T1az57p9vrmYj8vdNe
Sign in to join this conversation on GitHub.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant